﻿
//==============================================================================
// 文件     ：ClassHelper.cs
// 功能概要 ：
//           
//           
// 作者    ：周薇
// 时间    ：2011年10月31日
// Copyright (c) 2011 重庆安运科技公司. All rights reserved.
//==============================================================================
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.ComponentModel;
using System.Reflection;
using System.Xml;
using System.Collections.Concurrent;
using System.Reflection.Emit;

namespace Webcar.Utils
{
    public static class DynamicFactory
    {
        private static ConcurrentDictionary<Type, Type> s_dynamicTypes = new ConcurrentDictionary<Type, Type>();

        private static Func<Type, Type> s_dynamicTypeCreator = new Func<Type, Type>(CreateDynamicType);

        public static object ToDynamic(this object entity)
        {
            var entityType = entity.GetType();
            var dynamicType = s_dynamicTypes.GetOrAdd(entityType, s_dynamicTypeCreator);

            var dynamicObject = Activator.CreateInstance(dynamicType);
            foreach (var entityProperty in entityType.GetProperties())
            {
                var value = entityProperty.GetValue(entity, null);
                dynamicType.GetField(entityProperty.Name).SetValue(dynamicObject, value);
            }

            return dynamicObject;
        }

        private static Type CreateDynamicType(Type entityType)
        {
            var asmName = new AssemblyName("DynamicAssembly_" + Guid.NewGuid());
            var asmBuilder = AppDomain.CurrentDomain.DefineDynamicAssembly(asmName, AssemblyBuilderAccess.Run);
            var moduleBuilder = asmBuilder.DefineDynamicModule("DynamicModule_" + Guid.NewGuid());

            var typeBuilder = moduleBuilder.DefineType(
                entityType.GetType() + "$DynamicType",
                TypeAttributes.Public);

            typeBuilder.DefineDefaultConstructor(MethodAttributes.Public);

            foreach (var entityProperty in entityType.GetProperties())
            {
                typeBuilder.DefineField(entityProperty.Name, entityProperty.PropertyType, FieldAttributes.Public);
            }

            return typeBuilder.CreateType();
        }
    }

    public static class ClassHelper
    {
        public static void CopyPropertyTo(this object from,object to)
        {
            foreach (var item in from.GetType().GetProperties(BindingFlags.Instance|BindingFlags.Public|BindingFlags.GetProperty))
            {
                object value = item.GetValue(from, null);
                var prop = to.GetType().GetProperty(item.Name);
                if (prop == null) continue;
                if (!prop.CanWrite) continue;
                if (prop.PropertyType == item.PropertyType)
                {
                    prop.SetValue(to, value,null);
                }
            }
        }
        /// <summary>
        /// 是否对象是null。
        /// </summary>
        /// <param name="obj"></param>
        /// <returns></returns>
        public static bool IsNullValue(this object obj)
        {
            if (Convert.IsDBNull(obj) || obj == null) return true;
            
            Type t = obj.GetType();
            if (t == typeof(string))
            {
                return obj.ToString().IsNull();
            }
            if (t == typeof(DateTime))
                return DateTime.Parse(obj.ToString()) == DateTime.MinValue;

            //if (obj.ToString().IsNumber())
            //    return obj.ToString().ToInt64() == 0;
            return false;
        }
        public static string GetDescription(object obj)
        {
            StringBuilder sb = new StringBuilder(300);
            foreach (var item in obj.GetType().GetProperties())
            {
                try
                {
                    sb.Append(item.Name + "=" + item.GetValue(obj, null).ToSafeString());
                }
                catch(Exception ex)
                {
                    sb.Append(item.Name + "=" + ex.Message);
                }

                sb.Append(Environment.NewLine);
            }
            return sb.ToString();
            //LoggerProvider.FreeLog("log\\empty_image.log", sb.ToString());
        }
    }
}
